package com.cfl.elasticsearch.utils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;


public class ElasticsearchUtils {

	private Client client;
	
	public static class ElasticsearchUtilsHolder {
		public static ElasticsearchUtils instance = new ElasticsearchUtils();
	}
	private ElasticsearchUtils() {
		// 初始化
		Settings settings = Settings.settingsBuilder().put("cluster.name","elast").build();
		try {
			client = TransportClient.builder().settings(settings).build()
			.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	};
	public static ElasticsearchUtils share() {
		ElasticsearchUtils elastsearchUtils = ElasticsearchUtilsHolder.instance;
		return elastsearchUtils;
	}
	
	public static void main(String[] args) throws Exception {
		
//		ElasticsearchUtils elastsearchUtils = ElasticsearchUtils.share();
		
//		// 插入索引
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("id", 1);
//		map.put("name", "小正");
//		map.put("age", 27);
//		map.put("sex", 0);
//		elastsearchUtils.index("account", "user", "1", map);
		
//		// 获取索引
//		Map<String, Object> map = elastsearchUtils.getById("account", "user", "1");
//		if(map != null)
//		{
//			for(Entry<String, Object> entity : map.entrySet()) {
//				System.out.println("key:" + entity.getKey() + "          value:" + entity.getValue());
//			}
//		}
		
//		// 分页条件查询
//		List<Map<String, Object>> maps = elastsearchUtils.getByNamePage("account", "user", "小正", 0, 18, 30);
//		for (Map<String, Object> map : maps) {
//			for(Entry<String, Object> entity : map.entrySet()) {
//				System.out.println("key:" + entity.getKey() + "          value:" + entity.getValue());
//			}
//		}
		
		// 修改
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("name", "李四");
//		updateById("account", "user", "2", map);
		
		// 删除索引
//		deleteById("account", "user", "3");
	}
	
	/**
	 * 插入索引
	 * @param index 索引库(数据库)
	 * @param type 类型(表)
	 * @param documentId 文本id(行id)
	 * @param map (数据)
	 */
	public void index(String index, String type, String documentId, Map<String, Object> map) {
		// 插入索引
		client.prepareIndex(index, type, documentId).setSource(map).execute().actionGet();
	}
	
	/**
	 * 获取索引
	 * @param index 索引库
	 * @param type 类型(表)
	 * @param documentId 文本id(行id)
	 * @return
	 */
	public Map<String, Object> getById(String index, String type, String documentId)
	{
		Map<String, Object> map = null;
		GetResponse getResponse = client.prepareGet(index, type, documentId).get();
		if(getResponse != null)
		{
			map = getResponse.getSource();
		}
		return map;
	}
	
	/**
	 * 根据名称分页获取数据
	 * @param index
	 * @param type
	 * @param name
	 * @return
	 */
	public List<Map<String, Object>> getByNamePage(String index, String type, String name, Integer sex, Integer minAge, Integer maxAge, int page, int pageSize)
	{
		// 查询条件
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		if(StringUtils.isNotEmpty(name))
		{
			boolQueryBuilder.must(QueryBuilders.matchQuery("name", name));		// 分词
		}
		if(sex != null)
		{
			boolQueryBuilder.must(QueryBuilders.termQuery("sex", sex));			// 不分词
		}
		if(pageSize == 0) pageSize = 20;
		
		List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
		SearchRequestBuilder search = client.prepareSearch(index);	// 索引库
		search.setTypes(type);										// 表
		search.setSearchType(SearchType.QUERY_THEN_FETCH);			// 查询方式
		search.setQuery(boolQueryBuilder);							// 查询条件
		if(minAge != null && maxAge != null)
		{
			search.setPostFilter(QueryBuilders.rangeQuery("age").from(minAge).to(maxAge));	// 过滤
		}
		search.setFrom((page-1)*pageSize).setSize(pageSize).setExplain(true);				// 分页
		SearchResponse response = search.execute().actionGet();		// 查询结构
		SearchHit[] searchHits = response.getHits().getHits();
		for(int i = 0; i < searchHits.length; i++)
		{
			SearchHit searchHit = searchHits[i];
			list.add(searchHit.getSource());
		}
		return list;
	}
	
	
	/**
	 * 修改索引
	 * @param index 索引库(数据库)
	 * @param type 类型(表)
	 * @param documentId 文本id(行id)
	 * @param map 数据
	 */
	public void updateById(String index, String type, String documentId, Map<String, Object> map)
	{
		UpdateRequest updateResponse = new UpdateRequest();
		updateResponse.index(index);
		updateResponse.type(type);
		updateResponse.id(documentId);
		updateResponse.doc(map);
		client.update(updateResponse);
	}
	
	/**
	 * 删除索引
	 * @param index 索引库
	 * @param type 类型(表)
	 * @param documentId 文本id(行id)
	 */
	public void deleteById(String index, String type, String documentId)
	{
		client.prepareDelete(index, type, documentId).get();
	}
}
